XDL ImageView 활용 여섯 번째

NXImageView를 활용하여 영상을 기반으로 하여 벡터 객체를 생성하는 기능을 구현합니다.

들어가기 전에

본 튜터리얼을 공부하기 전에 먼저 "XDL ImageView 활용 다섯 번째”를 먼저 선행하시기 바랍니다.

1 메뉴에 Open/Save 기능 넣기
1.1 디자인창에서 메뉴에 [File]-[Open], [File]-[Open XvcVector]와 [File]-[Save XvcVector]를 추가한다. 또한 [Save XvcVector] 메뉴 하부에 [Pixoneer XVML]과 [External Vector Format] 기능을 추가한다.
2 메뉴에 벡터 생성 추가
2.1 상위 메뉴로 Vector를 입력하고 다음과 같이 메뉴를 구성한다.
3 참조 dll 추가하기
3.1 [참조추가] 기능을 통해 “C:\Pixoneer\XDL3.0\bin” 폴더로 이동하여 NXDLvc.dll를 선택하여 추가한다.
4 코드 추가하기
4.1 생성된 벡터를 열거나 저장하기 위한 XVectorIO 객체를 생성한다.

C#

                                    
namespace XDL_ImageView6
{
    public partial class Form1 : Form
    {
        public XRasterIO m_RasterIO;        //영상의 입출력을 담당할 객체 선언
        public XVectorIO m_VectorIO;        //벡터 객체의 입출력을 담당할 객체 선언

        public Form1()
        {
        ...
                                    
                                

4.2 선언부에 벡터 객체를 핸들링하기 위해 “using Pixoneer.NXDL.NVC;”을 추가하고 생성자에 XImageLayerVectorEditor 객체에 편집이 가능하도록 Editable 속성을 true로 설정하고, m_VectorIO 객체를 생성 및 초기화한다.

C#

                                    
using Pixoneer.NXDL;        // 기본 함수 관련 기능
using Pixoneer.NXDL.NCC;    // 좌표 시스템 관련 기능
using Pixoneer.NXDL.NIO;    // 파일 입출력 관련 기능
using Pixoneer.NXDL.NRS;    // Remote Sensing 관련 기능
using Pixoneer.NXDL.NGR;    // Graphic관련 기능
using Pixoneer.NXDL.NVC;    // Vector 객체와 관련된 기능
using Pixoneer.NXDL.NXImage;  // ImageView 관련 기능

public Form1()
{
    InitializeComponent();

    String StrError;
    m_RasterIO = new XRasterIO();   // 객체 생성
    if (m_RasterIO.Initialize(out StrError) == false)   // 영상 입출력 객체 초기화
    {
        MessageBox.Show(StrError);
    }

    nxImageLayerComposites1.LayerVisible = true;

    if (!nxImageView1.SetBackgroundMap("C:\\Pixoneer\\XDL3.0\\Config\\XImageBase.xml"))
    {
        MessageBox.Show("배경맵이 설정되지 않았습니다.");
    }

    // 벡터 객체를 생성하고 편집하기 위해 
    nxImageLayerVectorEditor1.Editable = true;
    nxImageLayerVectorEditor1.UsableKeyboard = true;

    // 벡터를 저장하기 위해 벡터 IO객체를 생성
    m_VectorIO = new XVectorIO();
    if (m_VectorIO.Initialize(out StrError) == false)
        MessageBox.Show(StrError);
}
                                    
                                

4.3 [Vector] 하위 메뉴인 Point, Line, Ellipse, Rectangle, PolyLine, Polygon, Text, TextBox의 메뉴를 더블클릭하고 자동 함수를 생성하여 다음과 같이 코드를 작성한다.

C#

                                    
private void pointToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Point, null);
}

private void lineToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Line, null);
}

private void ellipseToolStripMenuItem_Click(object sender, EventArgs e)
{
   nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Ellipse, null);
}

private void rectangleToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Rectangle, null);
}

private void polyLineToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Polyline, null);
}

private void polygonToolStripMenuItem_Click(object sender, EventArgs e)
{
   nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Polygon, null);
}

private void textToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Text, null);
}

private void textBoxToolStripMenuItem_Click(object sender, EventArgs e)
{
   nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Textbox, null);
}
                                    
                                

4.4 측정도구를 위해 MeasurePoint, MeasureDistance, MeasureArea, MeasureAngle 메뉴를 더블 클릭하여 자동 코드를 생성하고 다음과 같이 코드를 삽입한다.

C#

                                    
private void measurePointToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasurePoint, null);
}

private void measureDistanceToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureDist, null);
}

private void measureAreaToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureArea, null);
}

private void measureAngleToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureAngle, null);
}
                                    
                                

4.5 특정 객체를 마우스로 선택한 뒤 속성값을 확인하고 변경하는 기능을 추가한다. [Vector]-[Property] 메뉴를 더블 클릭하여 코드를 생성한다.

C#

                                    
private void propertyToolStripMenuItem_Click(object sender, EventArgs e)
{
    XvcObj Obj = nxImageLayerVectorEditor1.GetSelectedObj();
    if (Obj == null) return;

    ChangeProperty(Obj);
}

public void ChangeProperty(XvcObj Obj)
{
    // 선택된 객체가 null인 경우는 실행하지 않는다.
    if (Obj == null) {   return;  }

    eXvcObjType type = Obj.Type;

    // Property 창을 생성하고 기존 Object의 속성값을 Property창에 설정한다. 
    PropertyXvcObj propertyDlg  = new PropertyXvcObj();
    propertyDlg.m_strObjType    = type.ToString();
    propertyDlg.m_nID           = Obj.ID;
    propertyDlg.m_strName       = Obj.Name;
    propertyDlg.m_crBack        = Obj.ColorBack;
    propertyDlg.m_crFore        = Obj.ColorFore;
    propertyDlg.m_crLine        = Obj.ColorLine;
    propertyDlg.m_dblThick      = Obj.GetThick();
    propertyDlg.m_StyleFill     = Obj.StyleFill;
    propertyDlg.m_StyleLine     = Obj.StyleLine;
    propertyDlg.m_crText        = Obj.ColorText;

    // Object Type에 따라 속성값을 Property창에 설정한다.
    if (type == eXvcObjType.Text)
    {
        propertyDlg.m_dblFontSize   = ((XvcText)Obj).FontSize;
        propertyDlg.m_strFontName   = ((XvcText)Obj).FontName;
        propertyDlg.m_bBold         = ((XvcText)Obj).Bold;
        propertyDlg.m_bUnderline    = ((XvcText)Obj).Underline;
        propertyDlg.m_bItalic       = ((XvcText)Obj).Italic;
        propertyDlg.m_bStrikeOut    = ((XvcText)Obj).StrikeOut;
    }
    else if (type == eXvcObjType.Line)
    {
        propertyDlg.m_LineStartShape = ((XvcLine)Obj).StartShapeType;
        propertyDlg.m_LineEndShape = ((XvcLine)Obj).EndShapeType;
    }

    // Object Type에 따라 속성값을 Property창에 설정한다.
    if (propertyDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        Obj.ID = propertyDlg.m_nID;
        Obj.Name = propertyDlg.m_strName;
        Obj.ColorBack = propertyDlg.m_crBack;
        Obj.ColorFore = propertyDlg.m_crFore;
        Obj.ColorLine = propertyDlg.m_crLine;
        Obj.SetThick(propertyDlg.m_dblThick);
        Obj.StyleFill = propertyDlg.m_StyleFill;
        Obj.StyleLine = propertyDlg.m_StyleLine;
        Obj.ColorText = propertyDlg.m_crText;

        // Object가 텍스트인경우 Text객체에 Property창에서 정의한 값을 설정한다.
        if (type == eXvcObjType.Text)
        {
            XvcText text = (XvcText)Obj;
            text.FontSize = propertyDlg.m_dblFontSize;
            text.FontName = propertyDlg.m_strFontName;
            text.Bold = propertyDlg.m_bBold;
            text.Underline = propertyDlg.m_bUnderline;
            text.Italic = propertyDlg.m_bItalic;
            text.StrikeOut = propertyDlg.m_bStrikeOut;
        }
        // Object가 Line인경우 Line객체에 Property창에서 정의한 값을 설정한다.
        else if (type == eXvcObjType.Line)
        {
            ((XvcLine)Obj).StartShapeType = propertyDlg.m_LineStartShape;
            ((XvcLine)Obj).EndShapeType = propertyDlg.m_LineEndShape;
        }

        this.nxImageView1.RefreshScreen();
    }
}
                                    
                                

4.6 [F5]키를 눌러 프로그램을 실행한다.

4.7 벡터 속성을 확인하고 수정하기 위한 폼 PropertyXvcObj.cs를 새로 추가하고 멤버변수 및 함수를 정의한다.

PropertyXvcObj.cs의 코드는 여기에서는 생략하도록 하겠으니, 샘플코드를 다운로드받아 참고하기 바란다.


4.8 [F5]키를 눌러 프로그램을 실행한다. 메뉴 [Vector]-[Line]을 선택한 후 라인을 하나 그린다.

4.9 생성한 라인 객체를 마우스로 선택한다. [Vector]-[Property] 메뉴를 누른다.

4.10 속성값을 변경 후 OK를 클릭한다.

변경한 속성값이 반영되어 화면에 라인이 도시되는 것을 확인한다.

1 메뉴에 Open/Save 기능 넣기
1.1 프로젝트 이름으로 "XDL_ImageView6"으로 하여 "WPF 앱(.NET Framework)" 생성한다.

1.2 "영상도시 툴 만들기 5"의 추가한 참조 dll과 함께, System.Drawing.dll도 함께 추가한다.

1.3 Window 창에 MenuItem을 이용하여 [File]-[Open XvcVector]와 [File]-[Save XvcVector] 메뉴를 추가한다. 또한 [Save XvcVector] 메뉴 하부에 [Pixoneer XVML]과 [External Vector Format] 메뉴를 추가한다.

Control type Header Name
MenuItem _Open XvcVector openVectorFileMenuItem

Control type Header Name
MenuItem _Save XvcVector
MenuItem _Pixoneer XVML pixoneerXVMLFileMenuItem
MenuItem _External Vector Format externalVectorFormatFileMenuItem
2 메뉴에 벡터 생성 추가
2.1 상위 메뉴로 Vector를 입력하고 다음과 같이 메뉴를 구성한다.

Control type Header Name
MenuItem _Vector
MenuItem _Point pointVectorMenuItem
MenuItem _Line lineVectorMenuItem
MenuItem _Ellipse ellipseVectorMenuItem
MenuItem _Rectangle rectangleVectorMenuItem
MenuItem _PolyLine polyLineVectorMenuItem
MenuItem _Polygon polygonVectorMenuItem
MenuItem _Text textVectorMenuItem
MenuItem _Text Box textBoxVectorMenuItem
MenuItem _Measure
MenuItem _MeasurePoint measurePointVectorMenuItem
MenuItem _MeasureDistance measureDistanceVectorMenuItem
MenuItem _MeasureArea measureAreaVectorMenuItem
MenuItem _MeasureAngle measureAngleVectorMenuItem
MenuItem _Property propertyVectorMenuItem
3 참조 dll 추가하기
3.1 [참조추가] 기능을 통해 “C:\Pixoneer\XDL3.0\bin” 경로의 NXDLvc.dll를 선택하여 추가한다.
4 코드 추가하기
4.1 생성된 벡터를 저장하고 다시 열기 위한 XVectorIO 객체를 생성한다.

C#

                                    
namespace XDL_ImageView6
{
    public partial class MainWindow : Window
    {
        public XRasterIO m_RasterIO;   // 영상의 입출력을 담당할 객체 선언
        public XVectorIO m_VectorIO;   //벡터 객체의 입출력을 담당할 객체 선언
       
        public MainWindow()
        {
                                    
                                

4.2 선언부에 벡터 객체를 핸들링하기 위해 “using Pixoneer.NXDL.NVC;”을 추가하고 생성자에 XMapLayerVectorEditor 객체에 편집이 가능하도록 Editable속성을 true로 설정하고, m_VectorIO 객체를 생성 및 초기화한다.

C#

                                    
using Pixoneer.NXDL;            // 기본 함수 관련 기능
using Pixoneer.NXDL.NIO;        // 파일 입출력 관련 기능
using Pixoneer.NXDL.NRS;        // Remote Sensing 관련 기능
using Pixoneer.NXDL.NVC;        // Vector 객체와 관련된 기능
using Pixoneer.NXDL.NXImage;    // MapView 관련 기능
using Microsoft.Win32;          // 파일 열기/저장 대화상자 관련 클래스

public MainWindow()
{
    InitializeComponent();
    String StrError;
    m_RasterIO = new XRasterIO();                       // 객체 생성
    if (m_RasterIO.Initialize(out StrError) == false)   // 영상 입출력 객체 초기화
    {
           System.Windows.Forms.MessageBox.Show(StrError);
    }
    nxImageLayerComposite1.LayerVisible = true;         // 영상레이어를 보이도록 속성을 변경

    if (!nxImageView1.SetBackgroundMap("C:\\Pixoneer\\XDL3.0\\Config\\XMapBase.xml"))
    {
            System.Windows.MessageBox.Show("배경맵이 설정되지 않았습니다.");
    }

    // 벡터 객체를 생성하고 편집하기 위해 
    nxImageLayerVectorEditor1.Editable = true;

    // 벡터를 저장하기 위해 벡터 IO객체를 생성
    m_VectorIO = new XVectorIO();
    if (m_VectorIO.Initialize(out StrError) == false)
        MessageBox.Show(StrError);
}
                                    
                                

4.3 [File] 하부에 [Open XvcVector]과 [Save XvcVector]에 대한 메뉴를 더블 클릭하고 자동 함수를 생성하여 다음과 같이 코드를 생성한다.

C#

                                    
// Vector 객체 로딩
private void openXvcVectorFileMenuItem_Click(object sender, RoutedEventArgs e)
{
     // 열기위한 파일 다이얼로그 창 생성
     OpenFileDialog openFileDialog = new OpenFileDialog();
     openFileDialog.Multiselect = false;
     openFileDialog.Filter = "XvcBase Files|*.xvml";
     openFileDialog.RestoreDirectory = true;

      Nullable<bool> result = openFileDialog.ShowDialog();
      if (result != true) return;

      // XvcBase객체 생성(XvcObject들을 담기 위한 최상위 객체)
      String strError;
      XvcBase vcBase = new XvcBase();

      // XvcBase객체 로딩
      bool bres = vcBase.LoadFile(openFileDialog.FileName, out strError, null);

      if (bres)
       MessageBox.Show("Vector File Open Succeed", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
      else
      {
          MessageBox.Show("Vector File Open Failed", "Fail", MessageBoxButton.OK, MessageBoxImage.Error);
          return;
      }

      // 로딩된 XvcBase객체를 XimageLayerVectorEditor 객체에 설정하여 재 편집이 가능하도록 설정
      nxImageLayerVectorEditor1.SetEditBase(vcBase);
}
                                    
                        	    

C#

                                    
// 내부 xml 포맷인 XVML 파일로 저장
private void pixoneerXVMLFileMenuItem_Click(object sender, RoutedEventArgs e)
{
      // XvcBase 객체 생성(XvcObject들을 담기 위한 최상위 객체)
      Pixoneer.NXDL.NVC.XvcBase vcbase = nxImageLayerVectorEditor1.GetEditBase();
      if (vcbase == null) return;

      // 저장 경로 생성을 위한 Save 파일 다이얼로그 생성
      SaveFileDialog dialog = new SaveFileDialog();
      dialog.Title = "Save XvcBase File";
      dialog.DefaultExt = "xvml";
      dialog.Filter = "XvcBase Files|*.xvml";

      Nullable<bool> result = dialog.ShowDialog();
      if (result == true )
      {
        String strError;

        // XvcBase에 저장된 객체를 파일로 저장
        bool bres = vcbase.SaveFile(dialog.FileName, out strError, null);

        if (bres)
            MessageBox.Show("Vector File Save Succeed", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
        else
            MessageBox.Show("Vector File Save Failed", "Fail", MessageBoxButton.OK, MessageBoxImage.Error);
    }         
}
                                    
                        	    

C#

                                    
// XDL이 지원하는 외부 벡터 객체를 로딩
private void externalVectorFormatFileMenuItem_Click(object sender, RoutedEventArgs e)
{
    // XImageLayerVectorEditor객체에 있는 XvcBase객체를 꺼내기.
    XvcBase vcbase = nxImageLayerVectorEditor1.GetEditBase();
    if (vcbase == null) return;

    // XDL이 지원하는 File filter 꺼내기
    String fileFilters = "";
    String fileFilters = m_VectorIO.GetFiltersForSave(ref fileFilters);

    // 외부 파일로 저장하기 위해 저장 다이얼로그 생성
    SaveFileDialog dialog = new SaveFileDialog();
    dialog.Filter = fileFilters;

    Nullable<bool> result = dialog.ShowDialog();
    if (result == true) 
    {
        String vectorFileName = dialog.FileName;
        String VectorFileKey = ExtractFilterKey(fileFilters, dialog.FilterIndex - 1);

        String strError;

        // 벡터를 외부 파일로 저장.
        bool bres = m_VectorIO.Export(ref vcbase, dialog.FileName, VectorFileKey, out strError, null);

        if (bres)
            MessageBox.Show("Vector File Save Succeed", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
        else
            MessageBox.Show("Vector File Save Failed", "Fail", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private String ExtractFilterKey(String strFilter, int idx)
{
    int tempidx = 0;
    String strKey = "";

    do
    {
        int idxDelim = strFilter.IndexOf(";|");
        if (idxDelim != -1)
        {
            String strKeyTemp = strFilter.Substring(0, idxDelim).Trim();
            int idxPipe = strKeyTemp.IndexOf('|');
            if (idxPipe != -1)
            {
                strKey = strKeyTemp.Substring(0, idxPipe).Trim();
            }
            else
            {
                strKey = strKeyTemp;
            }

            strFilter = strFilter.Remove(0, idxDelim + 2);
            tempidx++;
        }
    } while (tempidx <= idx);
    return strKey;
}
                                    
                        	    

4.4 [Vector] 하위 메뉴 [Point], [Line], [Ellipse], [Rectangle], [PolyLine], [Polygon,] [Text], [Text Box]의 메뉴를 더블클릭하고 자동 함수를 생성하여 다음과 같이 코드를 생성한다.

C#

                                    
private void pointVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Point, null);
}

private void lineVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Line, null);
}

private void ellipseVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Ellipse, null);
}

private void rectangleVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Rectangle, null);
}

private void polyLineVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Polyline, null);
}

private void polygonVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
   nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Polygon, null);
}

private void textVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Text, null);
}

private void textBoxVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
   nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.Textbox, null);
}
                                    
                        	    

4.5 측정도구를 위해 [MeasurePoint], [MeasureDistance], [MeasureArea], [MeasureAngle] 를 더블 클릭하여 자동 코드를 생성하고 다음과 같이 코드를 삽입한다.

C#

                                    
private void measurePointVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasurePoint, null);
}

private void measureDistanceVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureDist, null);
}

private void measureAreaVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureArea, null);
}

private void measureAngleVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
nxImageLayerVectorEditor1.CreateNewOBJ(Pixoneer.NXDL.NVC.eXvcObjType.MeasureAngle, null);
}
                                    
                        	    

4.6 특정 객체를 마우스로 선택한 뒤 속성값을 확인하고 변경하는 기능을 추가한다. [Vector]-[Property] 버튼을 더블 클릭하여 코드를 생성한다.

C#

                                    
private void propertyVectorMenuItem_Click(object sender, RoutedEventArgs e)
{
        XvcObj Obj = nxImageLayerVectorEditor1.GetSelectedObj();
        if (Obj == null) return;
        ChangeProperty(Obj);
}

public void ChangeProperty(XvcObj Obj)
{
       // 선택된 객체가 null인 경우는 실행하지 않는다.
       if (Obj == null) { return; }

       eXvcObjType type = Obj.Type;

       // Property 창을 생성하고 기존 Object의 속성값을 Property창에 설정한다.
       PropertyXvcObj propertyDlg = new PropertyXvcObj();
       propertyDlg.m_strObjType = type.ToString();
       propertyDlg.m_nID = Obj.ID;
       propertyDlg.m_strName = Obj.Name;
       propertyDlg.m_crBack = Obj.ColorBack;
       propertyDlg.m_crFore = Obj.ColorFore;
       propertyDlg.m_crLine = Obj.ColorLine;
       propertyDlg.m_crText = Obj.ColorText;
       propertyDlg.m_dblThick = Obj.GetThick();
       propertyDlg.m_StyleFill = Obj.StyleFill;
       propertyDlg.m_StyleLine = Obj.StyleLine;

       //propertyDlg.Show();
            
       // Object Type에 따라 속성값을 Property창에 설정한다.
      if (type == eXvcObjType.Text)
      {
            propertyDlg.m_dblFontSize = ((XvcText)Obj).FontSize;
            propertyDlg.m_strFontName = ((XvcText)Obj).FontName;
            propertyDlg.m_bBold = ((XvcText)Obj).Bold;
            propertyDlg.m_bUnderline = ((XvcText)Obj).Underline;
            propertyDlg.m_bItalic = ((XvcText)Obj).Italic;
            propertyDlg.m_bStrikeOut = ((XvcText)Obj).StrikeOut;
       }

       else if (type == eXvcObjType.Line)
       {
            propertyDlg.m_LineStartShape = ((XvcLine)Obj).StartShapeType;
            propertyDlg.m_LineEndShape = ((XvcLine)Obj).EndShapeType;
       }

       // Object Type에 따라 속성값을 Property창에 설정한다.
       if((bool)propertyDlg.ShowDialog())
       {
            Obj.ID = propertyDlg.m_nID;
            Obj.Name = propertyDlg.m_strName;
            Obj.ColorBack = propertyDlg.m_crBack;
            Obj.ColorFore = propertyDlg.m_crFore;
            Obj.ColorLine = propertyDlg.m_crLine;
            Obj.SetThick(propertyDlg.m_dblThick);
            Obj.StyleFill = propertyDlg.m_StyleFill;
            Obj.StyleLine = propertyDlg.m_StyleLine;
            Obj.ColorText = propertyDlg.m_crText;

           // Object가 텍스트인경우 Text객체에 Property창에서 정의한 값을 설정한다.
           if (type == eXvcObjType.Text)
           {
               XvcText text = (XvcText)Obj;
               text.FontSize = propertyDlg.m_dblFontSize;
               text.FontName = propertyDlg.m_strFontName;
               text.Bold = propertyDlg.m_bBold;
               text.Underline = propertyDlg.m_bUnderline;
               text.Italic = propertyDlg.m_bItalic;
               text.StrikeOut = propertyDlg.m_bStrikeOut;
           }
           // Object가 Line인경우 Line객체에 Property창에서 정의한 값을 설정한다.
           else if (type == eXvcObjType.Line)
           {
               ((XvcLine)Obj).StartShapeType = propertyDlg.m_LineStartShape;
               ((XvcLine)Obj).EndShapeType = propertyDlg.m_LineEndShape;
           }
           this.nxImageView1.RefreshScreen();
       }
}
                                    
                        	    

4.7 [F5] 키를 눌러 프로그램을 실행한다. [Vector] 메뉴 [Line], [Polygon] 등을 선택한 후 도시 화면 위에 마우스 클릭, 이동, 끌기 등과 같은 동작으로 객체를 생성한다.

PolyLine, Polygon, MeasureDistance, MeasureArea 은 더블클릭하여 생성을 끝마친다.


4.8 페이지(WPF)를 솔루션에 새롭게 추가하고 디자인한다.

새로운 Window를 추가하려면, Visual Studio의 메뉴 [프로젝트]-[페이지 추가]를 선택하거나, [솔루션 탐색기]에서 프로젝트를 선택한 후 마우스 오른쪽 버튼을 클릭하여 생성되는 메뉴에서 [추가]-[페이지]을 선택한다.


이름은 “PropertyXvcObj.xaml”으로 한다.


4.9 XAML 창을 생성하여 Property 창을 디자인한다.

Property 창 코드는 여기에서 생략한다. 샘플코드를 다운로드받아 참고하기 바란다.


4.10 [F5]키를 눌러 프로그램을 실행한다.. [Vector]-[Line]를 눌러 라인을 하나 그린다.

4.12 생성한 라인을 선택하고, [Vector]-[Property] 메뉴를 클릭한다.

4.12 속성값을 변경 후 OK를 클릭한다.

변경한 속성값이 반영되어 화면에 라인이 도시되는 것을 확인한다.